home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre1.z / postgre1 / test / postfs / icopy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  8.0 KB  |  405 lines

  1. /*
  2.  *  icopy -- Inversion file system copy program
  3.  *
  4.  *    Icopy moves files between the Unix file system and Inversion.
  5.  */
  6.  
  7. #include <sys/file.h>
  8. #include <stdio.h>
  9.  
  10. #include "tmp/c.h"
  11. #include "tmp/libpq-fe.h"
  12. #include "tmp/libpq-fs.h"
  13. #include "catalog/pg_lobj.h"
  14.  
  15. RcsId("$Header: /private/postgres/test/postfs/RCS/icopy.c,v 1.2 1992/06/30 21:04:18 mao Exp $");
  16.  
  17. #define    DIR_IN    0
  18. #define    DIR_OUT    1
  19. #define IBUFSIZ    8092
  20.  
  21. #ifndef TRUE
  22. #define    TRUE    1
  23. #define    FALSE    0
  24. #endif /* ndef TRUE */
  25.  
  26. char *ProgName;
  27. extern char *PQhost;
  28. extern char *PQport;
  29.  
  30. /* routines declared here */
  31. extern char    *nextarg();
  32. extern void    icopy_in();
  33. extern void    icopy_out();
  34. extern void    isetup();
  35. extern void    ishutdown();
  36. extern void    usage();
  37.  
  38. /* routines declared elsewhere */
  39. extern char    *getenv();
  40.  
  41. char *SmgrList[] = {
  42.     "magnetic disk",
  43. #ifdef SONY_JUKEBOX
  44.     "sony jukebox",
  45. #endif
  46. #ifdef MAIN_MEMORY
  47.     "main memory",
  48. #endif
  49.     (char *) NULL
  50. };
  51.  
  52. main(argc, argv)
  53.     int argc;
  54.     char **argv;
  55. {
  56.     int dir;
  57.     char *dbname;
  58.     char *smgr;
  59.     int smgrno;
  60.     char *host, *port;
  61.     char *srcfname, *destfname;
  62.     char *curarg;
  63.  
  64.     host = port = dbname = smgr = srcfname = destfname = (char *) NULL;
  65.     ProgName = *argv;
  66.     smgrno = 0;
  67.  
  68.     if (--argc == 0)
  69.     usage();
  70.  
  71.     /* copy direction */
  72.     if (strcmp(*++argv, "in") == 0)
  73.     dir = DIR_IN;
  74.     else if (strcmp(*argv, "out") == 0)
  75.     dir = DIR_OUT;
  76.     else
  77.     usage();
  78.  
  79.     while (--argc) {
  80.     ++argv;
  81.     if (**argv == '-') {
  82.         curarg = *argv;
  83.         switch (*++(*argv)) {
  84.           case 'd':
  85.         dbname = nextarg(&argc, &argv);
  86.         break;
  87.  
  88.           case 'h':
  89.         host = nextarg(&argc, &argv);
  90.         break;
  91.  
  92.           case 'p':
  93.         port = nextarg(&argc, &argv);
  94.         break;
  95.  
  96.           case 's':
  97.         smgr = nextarg(&argc, &argv);
  98.         break;
  99.  
  100.           /*
  101.            *  This case handles "-" as a filename (meaning stdout
  102.            *  or stdin).
  103.            */
  104.           case '\0':
  105.         if (srcfname == (char *) NULL)
  106.             srcfname = curarg;
  107.         else if (destfname == (char *) NULL)
  108.             destfname = curarg;
  109.         else
  110.             usage();
  111.         break;
  112.  
  113.           default:
  114.         usage();
  115.         }
  116.     } else if (srcfname == (char *) NULL)
  117.         srcfname = *argv;
  118.     else if (destfname == (char *) NULL)
  119.         destfname = *argv;
  120.     else
  121.         usage();
  122.     }
  123.  
  124.     if (srcfname == (char *) NULL || destfname == (char *) NULL)
  125.     usage();
  126.  
  127.     if (host == (char *) NULL) {
  128.     if ((host = getenv("PGHOST")) == (char *) NULL) {
  129.         fprintf(stderr, "no host specified and PGHOST undefined.\n");
  130.         usage();
  131.     }
  132.     }
  133.  
  134.     if (port == (char *) NULL) {
  135.     if ((port = getenv("PGPORT")) == (char *) NULL) {
  136.         fprintf(stderr, "no port specified and PGPORT undefined.\n");
  137.         usage();
  138.     }
  139.     }
  140.  
  141.     if (dbname == (char *) NULL)
  142.     usage();
  143.  
  144.     if (dir == DIR_IN &&
  145.     (smgr == (char *) NULL || (smgrno = smgrlookup(smgr)) < 0))
  146.     usage();
  147.  
  148.     isetup(host, port, dbname);
  149.  
  150.     if (dir == DIR_IN)
  151.     icopy_in(srcfname, destfname, smgrno);
  152.     else
  153.     icopy_out(srcfname, destfname, smgrno);
  154.  
  155.     ishutdown();
  156.  
  157.     exit (0);
  158. }
  159.  
  160. void
  161. icopy_in(srcfname, destfname, smgrno)
  162.     char *srcfname;
  163.     char *destfname;
  164.     int smgrno;
  165. {
  166.     int srcfd, destfd;
  167.     char *buf, *lbuf;
  168.     int nread, nwrite, totread, nbytes;
  169.     int done;
  170.  
  171.     /* copy in cannot go to stdout */
  172.     if (strcmp(destfname, "-") == 0)
  173.     usage();
  174.  
  175.     if (strcmp(srcfname, "-") == 0)
  176.     srcfd = fileno(stdin);
  177.     else if ((srcfd = open(srcfname, O_RDONLY, 0600)) < 0) {
  178.     perror(ProgName);
  179.     exit (1);
  180.     }
  181.  
  182.     if ((destfd = p_creat(destfname, INV_WRITE|smgrno, Inversion)) < 0) {
  183.     fprintf(stderr, "Cannot create Inversion file %s\n", destfname);
  184.     fflush(stderr);
  185.     exit (1);
  186.     }
  187.  
  188.     if ((buf = (char *) malloc(IBUFSIZ)) == (char *) NULL) {
  189.     fprintf(stderr, "cannot allocate %d bytes for copy buffer\n", IBUFSIZ);
  190.     fflush(stderr);
  191.     exit (1);
  192.     }
  193.  
  194.     done = FALSE;
  195.     while (!done) {
  196.     lbuf = buf;
  197.     totread = 0;
  198.     nbytes = IBUFSIZ;
  199.  
  200.     /* read one inversion file system buffer's worth of data */
  201.     while (nbytes > 0) {
  202.         if ((nread = read(srcfd, lbuf, nbytes)) < 0) {
  203.         perror(ProgName);
  204.         exit (1);
  205.         } else if (nread == 0) {
  206.         nbytes = 0;
  207.         done = TRUE;
  208.         } else {
  209.         nbytes -= nread;
  210.         totread += nread;
  211.         lbuf += nread;
  212.         }
  213.     }
  214.  
  215.     /* write it out to the inversion file */
  216.     lbuf = buf;
  217.     while (totread > 0) {
  218.         if ((nwrite = p_write(destfd, lbuf, totread)) <= 0) {
  219.         fprintf(stderr, "%s: write failed to Inversion file %s\n",
  220.             ProgName, destfname);
  221.         fflush(stderr);
  222.         exit (1);
  223.         }
  224.         totread -= nwrite;
  225.         lbuf += nwrite;
  226.     }
  227.     }
  228.  
  229.     (void) close(srcfd);
  230.     (void) p_close(destfd);
  231. }
  232.  
  233. void
  234. icopy_out(srcfname, destfname, smgrno)
  235.     char *srcfname;
  236.     char *destfname;
  237.     int smgrno;
  238. {
  239.     int srcfd, destfd;
  240.     char *buf, *lbuf;
  241.     int nread, nwrite, totread, nbytes;
  242.     int done;
  243.  
  244.     /* copy out cannot come from stdin */
  245.     if (strcmp(srcfname, "-") == 0)
  246.     usage();
  247.  
  248.     if ((srcfd = p_open(srcfname, INV_READ)) < 0) {
  249.     fprintf(stderr, "%s: cannot open Inversion file %s\n",
  250.         ProgName, srcfname);
  251.     fflush(stderr);
  252.     exit (1);
  253.     }
  254.  
  255.     if (strcmp(destfname, "-") == 0)
  256.     destfd = fileno(stdout);
  257.     else if ((destfd = open(destfname, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
  258.     perror(ProgName);
  259.     exit (1);
  260.     }
  261.  
  262.     if ((buf = (char *) malloc(IBUFSIZ)) == (char *) NULL) {
  263.     fprintf(stderr, "cannot allocate %d bytes for copy buffer\n", IBUFSIZ);
  264.     fflush(stderr);
  265.     exit (1);
  266.     }
  267.  
  268.     done = FALSE;
  269.     while (!done) {
  270.     lbuf = buf;
  271.     totread = 0;
  272.     nbytes = IBUFSIZ;
  273.  
  274.     /* read one inversion file system buffer's worth of data */
  275.     while (nbytes > 0) {
  276.         if ((nread = p_read(srcfd, lbuf, nbytes)) < 0) {
  277.         fprintf(stderr, "%s: read failed from inversion file %s\n",
  278.             ProgName, srcfname);
  279.         fflush(stderr);
  280.         exit (1);
  281.         } else if (nread == 0) {
  282.         nbytes = 0;
  283.         done = TRUE;
  284.         } else {
  285.         nbytes -= nread;
  286.         totread += nread;
  287.         lbuf += nread;
  288.         }
  289.     }
  290.  
  291.     /* write it out to the unix file */
  292.     lbuf = buf;
  293.     while (totread > 0) {
  294.         if ((nwrite = write(destfd, lbuf, totread)) <= 0) {
  295.         perror(ProgName);
  296.         exit (1);
  297.         }
  298.         totread -= nwrite;
  299.         lbuf += nwrite;
  300.     }
  301.     }
  302.  
  303.     (void) p_close(srcfd);
  304.     (void) close(destfd);
  305. }
  306.  
  307. void
  308. isetup(host, port, dbname)
  309.     char *host;
  310.     char *port;
  311.     char *dbname;
  312. {
  313.     char *res;
  314.  
  315.     PQport = port;
  316.     PQhost = host;
  317.     PQsetdb(dbname);
  318.  
  319.     res = PQexec("begin");
  320.     if (*res == 'E') {
  321.     fprintf(stderr, "%s: begin xact failed: %s\n", ProgName, *++res);
  322.     fflush(stderr);
  323.     exit (1);
  324.     }
  325. }
  326.  
  327. void
  328. ishutdown()
  329. {
  330.     char *res;
  331.  
  332.     res = PQexec("end");
  333.     if (*res == 'E') {
  334.     fprintf(stderr, "%s: copy failed at commit: %s\n", ProgName, *++res);
  335.     fflush(stderr);
  336.     exit (1);
  337.     }
  338. }
  339. /*
  340.  *  nextarg() -- getopt()-style routine to get next arg.
  341.  *
  342.  *    This routine returns the string beginning after the option letter
  343.  *    in the current argument, if any, or the next argument otherwise.
  344.  *    Argc and argv are updated as appropriate.
  345.  */
  346.  
  347. char *
  348. nextarg(argc_p, argv_p)
  349.     int *argc_p;
  350.     char ***argv_p;
  351. {
  352.     if (*++(**argv_p) == '\0') {
  353.     if (--(*argc_p) == 0)
  354.         usage();
  355.         /* NOTREACHED */
  356.     else
  357.         return (*++(*argv_p));
  358.     } else
  359.     return (**argv_p);
  360. }
  361.  
  362. /*
  363.  *  smgrlookup() -- Look up a storage manager by name.
  364.  *
  365.  *    The offsets in the storage manager table compiled into this
  366.  *    program are the same as those used by the backend.  We rely
  367.  *    on this fact.
  368.  */
  369.  
  370. int
  371. smgrlookup(smgr)
  372.     char *smgr;
  373. {
  374.     int i;
  375.  
  376.     for (i = 0; SmgrList[i] != (char *) NULL; i++)
  377.     if (strcmp(smgr, SmgrList[i]) == 0)
  378.         return (i);
  379.  
  380.     return (-1);
  381. }
  382.  
  383. void
  384. usage()
  385. {
  386.     int i;
  387.  
  388.     fprintf(stderr, "usage: %s {in|out} ", ProgName);
  389.     fprintf(stderr, "-h host -p port -d db -s smgr from_file to_file\n\n");
  390.  
  391.     fprintf(stderr, "    'in' copies to Inversion, and 'out' copies from Inversion.\n\n");
  392.  
  393.     fprintf(stderr, "    smgr may be:\n");
  394.     for (i = 0; SmgrList[i] != (char *) NULL; i++)
  395.     fprintf(stderr, "\t%s\n", SmgrList[i]);
  396.     fprintf(stderr, "    smgr is ignored for %s out.\n", ProgName);
  397.  
  398.     fprintf(stderr, "\n    from_file or to_file may be '-', for stdin and stdout, respectively.\n");
  399.     fprintf(stderr, "    stdin may not be used with %s out.\n", ProgName);
  400.     fprintf(stderr, "    stdout may not be used with %s in.\n", ProgName);
  401.  
  402.     fflush(stderr);
  403.     exit (1);
  404. }
  405.